'use strict';

import { head, last, pick } from 'ramda';
import lokr from 'lockr';

import * as actionType from './action';

/**
 * Go to the previous tab
 * @method previous
 * @param  {Object} state
 * @return {Object} selected and its sibling tabs
 */
export function previous(state) {
  const { streamers, selected } = state;
  const previousTab = streamers[selected.id - 2] || last(streamers);
  if (previousTab.id === 0) {
    return pick(['selected', 'previous', 'next'],
                  state);
  }
  return {
    selected: previousTab,
    previous: streamers[previousTab.id - 2],
    next: selected,
  };
}
/**
 * Go to the next tab
 * @method next
 * @param {Object} state
 * @return {Object} selected and its sibling tabs
 */
export function next(state) {
  const { streamers, selected } = state;
  const nextTab = streamers[selected.id] || head(streamers);
  if (nextTab.id === streamers.length) {
    const current = pick(['selected', 'previous', 'next'],
                         state);
    return { selected: current.next,
             previous: current.selected,
             next: head(streamers) };
  }
  return {
    selected: nextTab,
    previous: selected,
    next: streamers[nextTab.id],
  };
}

/**
 * Get sibling tab
 * @method sibling
 * @param {Object} state
 * @return {Object} selected and its sibling tabs
 */
export function sibling(state) {
  const { streamers, selected } = state;
  const currentTab = streamers[selected.id - 1];
  return {
    selected: currentTab,
    previous: previous(state).selected,
    next: next(state).selected,
  };
}

/**
 * Remove a tab
 * @method remove
 * @param  {Array} streamers streamers list
 * @param  {Integer} id
 * @return {Array} streamers list, tab removed
 */
export function remove(streamers, id) {
  return streamers.filter(streamer => streamer.id !== id);
}

/**
 * Update a tab
 * @method update
 * @param  {Array} streamers streamers list
 * @param  {Integer} id
 * @param  {Object} payload
 * @return {Array} streamers list, tab updated
 */
export function update(streamers, id, payload) {
  const selected = head(streamers.filter(streamer => streamer.id === id));
  const updated = Object.assign({ }, selected, payload);
  return streamers.map(streamer => {
    if (streamer.id === id) {
      return updated;
    }
    return streamer;
  });
}

export function tabReducer(state, action) {
  if (!action) {
    return state;
  }
  switch (action.type) {
    case actionType.ADD_TAB: {
      const newState = Object.assign({ },
                                  state,
                                  { streamers: [...state.streamers, action.tab] });
      lokr.set('local', newState);
      return newState;
    }
    case actionType.SELECT_TAB: {
      const selected = head(
        state.streamers.filter(streamer => action.name === streamer.name)
      );
      return Object.assign({ },
                          state,
                          sibling(Object.assign({ },
                                                { streamers: state.streamers },
                                                { selected })));
    }
    case actionType.PREVIOUS_TAB:
      return Object.assign({ }, state, previous(state));
    case actionType.NEXT_TAB:
      return Object.assign({ }, state, next(state));
    case actionType.REMOVE_TAB:
      return Object.assign({ },
                           state,
                           { streamers: remove(state.streamers, action.id) });
    case actionType.EDIT_TAB:
      return Object.assign({ },
                           state,
                           { streamers: update(state.streamers,
                                                action.id,
                                                action.payload) });
    default:
      return state;
  }
}

export default tabReducer;
